/*
* $Id: ubecspi.c,v 1.4 2007/12/21 06:07:03 sunny Exp $
*/
/*******************************************************************************

       UBEC (Uniband Electronic Corp.)

       Project: U-NET01, Ubiquitous network platform

       File: ubecspi.c

       Version: 0.3.0

       Usage: UZ2400 SPI Interface Function

       Platform: U-NET01 DK with Keil 8051 C compiler

       Reference:

               Silicon Laboratories: C8051F124, C8051F340

               UBEC: UZ2400, UZ2410

       Note :

               Copyright (C) 2007 Uniband Electronic Corporation, All rights reserved

********************************************************************************/

#include "unet.h"

#ifndef IOUZ2410
#define spi_put(c)	spi_rw(c)
#define spi_get()	spi_rw(0)
#endif // #ifndef IOUZ2410

#ifndef IOUZ2410
void UzChipReset(void)
{
	UINT8		cnt;

	Link_LED_Off();
	RxTx_LED_Off();

	// Chip Reset
	UBEC_Activate_RESET();		// Put the RESET to Low
	for(cnt=0;cnt<100;cnt++) { NOP(); NOP();NOP();}

	UBEC_Deactivate_RESET();	// Put the RESET to High
	for(cnt=0;cnt<100;cnt++) { NOP(); NOP();NOP();}
}

void spi_sw(UINT8 Address, UINT8 Value)
{
#ifdef IOUZ2410

	*((XUINT8 *)(0xF800 + Address)) = Value;

#else

	DisInt();

	Address = (Address << 1) | 0x0001; //Shfit the Address

	UBEC_Activate_SEN();	//Put the CS to Low

	spi_put(Address);	//Write the address

	spi_put(Value);		//Write the data

	UBEC_Deactivate_SEN();	//Put the CS to High

	EnabInt();
#endif // #ifdef IOUZ2410
}
#endif // #ifndef IOUZ2410

#if !defined( IOUZ2410 ) || defined(UZ2410_VERSION_3)
#pragma message (__LOC__ "spi_sr() is called by interrupt service routine and main program.")
#if defined(__C51__)
#pragma NOAREGS
#endif
UINT8 spi_sr(UINT8 Address)
{
#ifdef IOUZ2410

    #ifdef UZ2410_VERSION_3
	ACC = *((volatile XUINT8 *)(0xF800 + Address));
    #endif // #ifdef UZ2410_VERSION_3

	return(*((volatile XUINT8 *)(0xF800 + Address)));

#else
	UINT8 Value;

	DisInt();

	Address = (Address << 1);

	UBEC_Activate_SEN();	//Put the CS to Low

	spi_put(Address);	//Write the address

	Value = spi_get();

	UBEC_Deactivate_SEN();	//Put the CS to High

	EnabInt();

	return Value;
#endif // #ifdef IOUZ2410
}
#if defined(__C51__)
#pragma AREGS
#endif
#endif // #ifndef IOUZ2410

#ifndef IOUZ2410
void spi_lw(UINT16 Address, UINT8 Value)
{
#ifdef IOUZ2410

	*((XUINT8 *)(0xFC00 + Address)) = Value;

#else
	DisInt();

	Address = (Address << 5) | 0x8010;

	UBEC_Activate_SEN();			//Put the CS to Low

	spi_put((UINT8)(Address >> 8));		//Write the address (high byte)

	spi_put((UINT8)(Address & 0xff));	//Write the address (low byte)

	spi_put(Value);				//Write the data

	UBEC_Deactivate_SEN();			//Put the CS to High

	EnabInt();
#endif // #ifdef IOUZ2410
}

UINT8 spi_lr(UINT16 Address)
{
#ifdef IOUZ2410

	return(*((volatile XUINT8 *)(0xFC00 + Address)));

#else
	UINT8 Value;

	DisInt();

	Address = (Address << 5) | 0x8000;

	UBEC_Activate_SEN();			//Put the CS to Low

	spi_put((UINT8)(Address >> 8));		//Write the address (high byte)

	spi_put((UINT8)(Address & 0xff));	//Write the address (low byte)

	Value = spi_get();

	UBEC_Deactivate_SEN();			//Put the CS to High

	EnabInt();

	return Value;
#endif // #ifdef IOUZ2410
}
#endif // #ifndef IOUZ2410

void spi_fill_fifo(UINT16 Address, UINT8 *DataPtr, UINT8 Length)
{
#ifdef IOUZ2410
	XUINT8 *Ptr;

	Ptr = (XUINT8 *)(0xFC00 + Address);
	while (Length--)
		*Ptr++ = *DataPtr++; //Write the data

#else
	DisInt();

	Address = (Address << 5) | 0x8010;

	UBEC_Activate_SEN();			//Put the CS to Low

	spi_put((UINT8)(Address >> 8));		//Write the address (high byte)

	spi_put((UINT8)(Address & 0xff));	//Write the address (low byte)

	while (Length--){
		spi_put(*DataPtr++);		//Write the data
	}

	UBEC_Deactivate_SEN();			//Put the CS to High

	EnabInt();
#endif
}

/*
void spi_dump_fifo(UINT16 Address, UINT8 *DataPtr, UINT8 Length)
{
#ifdef IOUZ2410

#else
	DisInt();

	Address = (Address << 5) | 0x8000;

	UBEC_Activate_SEN();			//Put the CS to Low

	spi_put((UINT8)(Address >> 8));		//Write the address (high byte)

	spi_put((UINT8)(Address & 0xff));	//Write the address (low byte)

	while(Length--){
		*DataPtr++ = spi_get();
	}

	UBEC_Deactivate_SEN();			//Put the CS to High

	EnabInt();
#endif // #ifdef IOUZ2410
}
*/

void spi_rd_rx_fifo(UINT8 *DataPtr, UINT8 buf_size)
{
#ifdef IOUZ2410
	UINT8 Length;
	volatile XUINT8 *Ptr;

	Ptr = (XUINT8 *)0xFF00;
	Length = *Ptr++ + 2; // LQI + RSSI
	if(Length > buf_size)
		Length = buf_size;	// 2007/8/8 10:12, Sunny: prevent buffer over-written

	while(Length--)
		*DataPtr++ = *Ptr++;

#else
	UINT8 Length;

	DisInt();

	UBEC_Activate_SEN();		//Put the CS to Low

	spi_put(0xE0);			//Write the address

	spi_put(0x00);			//Write the address

	Length = spi_get();

	//Length += MAC_EXTEND_DATA;
	//*RxLength = Length; // Header + Payload + FCS

	Length += 2; // LQI + RSSI
	if(Length > buf_size)
		Length = buf_size;	// 2007/8/8 10:12, Sunny: prevent buffer over-written

	while(Length--){
		*DataPtr++ = spi_get();
	}

	UBEC_Deactivate_SEN();		//Put the CS to High

	EnabInt();
#endif // #ifdef IOUZ2410
}
